<template>
  <div>
    <el-dialog
        model-value:visible="showCRMImport"
        :title="'导入'+crmTypeName"
        :append-to-body="true"
        :close-on-click-modal="false"
        width="750px"
        @close="closeView">
      <div class="dialog-body">
        <el-steps :active="stepsActive" simple>
          <el-step v-for="(item, index) in stepList" :key="index"
                   :title="item.title" :icon="item.icon" :status="item.status"/>
        </el-steps>

        <div v-if="stepsActive == 1" class="step-section">
          <div class="sections">
            <div class="sections__title">
              一、请按照数据模板的格式准备要导入的数据。
              <span class="download" @click="download">
              点击下载《{{ crmTypeName }}导入模板》
              </span>
            </div>
            <div class="sections__tips">导入文件请勿超过2MB（约10,000条数据）</div>
          </div>
          <div v-if="config.repeatHandleShow" class="sections">
            <div class="sections__title">
              二、请选择数据重复时的处理方式{{ config.repeatRuleShow ? `（查重规则：【${fieldUniqueInfo}】）` : '' }}
            </div>
            <div v-if="config.repeatRuleShow" class="sections__tips">
              查重规则为：添加{{
                crmTypeName
              }}时所需填写的所有唯一字段，当前设置唯一字段为：{{ fieldUniqueInfo }}
            </div>
            <div class="content">
              <el-select v-model="repeatHandling" placeholder="请选择">
                <el-option v-for="(item, index) in [{name: '覆盖系统原有数据',value: 1},{name: '跳过',value: 2}]"
                           :key="index"
                           :label="item.name"
                           :value="item.value"/>
              </el-select>
            </div>
          </div>
          <div class="sections">
            <div class="sections__title">{{ config.repeatHandleShow ? '三' : '二' }}、请选择需要导入的文件</div>
            <div class="content">
              <flexbox class="file-select">
                <el-input v-model="file.name" :disabled="true"/>
                <el-button type="primary" @click="selectFile">选择文件
                </el-button>
              </flexbox>
            </div>
          </div>
          <div v-if="config.ownerSelectShow" class="sections">
            <div class="sections__title">
              四、请选择负责人（负责人为必填字段，若不填写，则会导致导入失败）
            </div>
            <div class="content">
              <div class="user-cell">
                <WkUserSelect v-model="user" radio style="width: 100%;" @change="userSelect"/>
              </div>
            </div>
          </div>

          <div v-if="config.poolSelectShow" class="sections">
            <div class="sections__title">四、请选择公海</div>
            <div class="content">
              <div class="user-cell">
                <el-select v-model="poolId" placeholder="请选择">
                  <el-option v-for="item in poolList" :key="item.poolId"
                             :label="item.poolName"
                             :value="item.poolId"/>
                </el-select>
              </div>
            </div>
          </div>
        </div>

        <div v-loading="loading" v-else-if="stepsActive == 2"
             :element-loading-text="importLoadingText"
             element-loading-spinner="el-icon-loading"
             class="step-section">
          <div class="step-section__tips">
            当前数据正在导入，您可以点击【最小化】隐藏该页面，数据导入不受影响。
          </div>
        </div>

        <div v-loading="loading" v-else-if="stepsActive == 3" class="step-section">
          <div class="result-info">
            <i class="wk wk-success result-info__icon"/>
            <p class="result-info__des">数据导入完成</p>
            <p v-if="resultData" class="result-info__detail">
              导入总数据
              <span class="result-info__detail--all">{{ resultData.totalSize }}</span>
              条，
              <template v-if="resultData.updateSize">
                覆盖
                <span class="result-info__detail--suc">{{ resultData.updateSize }}</span>
                条，
              </template>
              导入成功
              <span class="result-info__detail--suc">
                {{ resultData.totalSize - resultData.errSize }}
              </span>
              条，导入失败
              <span class="result-info__detail--err">
                {{ resultData.errSize }}
              </span>
              条
            </p>
            <el-button v-if="resultData && resultData.errSize > 0"
                       class="result-info__btn--err"
                       link
                       @click="downloadErrData(resultData)">
              下载错误数据
            </el-button>
          </div>
        </div>

        <input id="importInputFile" type="file" @change="uploadFile">
      </div>
      <template v-slot:footer>
        <span class="dialog-footer">
        <el-popover v-if="config.historyShow" v-model:visible="historyPopoverShow"
                    placement="top"
                    width="800"
                    popper-class="no-padding-popover"
                    trigger="click">
          <import-history :show="historyPopoverShow"
                          :crm-type="crmType" :props="crmProps"
                          @close="historyPopoverShow = false"/>
          <template v-slot:reference>
          <el-button class="history-btn" link>
            查看历史导入记录
          </el-button>
          </template>

        </el-popover>
        <el-button :class="{ 'is-hidden': !showCancel }" @click="closeView">
          取消
        </el-button>
        <el-button v-if="sureTitle" type="primary" @click="sureClick">
          {{ sureTitle }}
        </el-button>
      </span>
      </template>

    </el-dialog>

    <XrImport v-if="showFixImport" :process-status="crmImportStatus" @click="fixImportClick"/>

  </div>
</template>

<script setup>


import {computed, getCurrentInstance, ref, watch} from "vue";
import {
  crmCustomerDownloadExcelAPI,
  crmCustomerExcelImportAPI,
  crmCustomerPoolDownloadExcelAPI,
  crmCustomerPoolExcelImportAPI, crmCustomerPoolNameListAPI
} from "@/api/crm/customer";
import {crmLeadsDownloadExcelAPI, crmLeadsExcelImportAPI} from "@/api/crm/leads";
import {crmContactsDownloadExcelAPI, crmContactsExcelImportAPI} from "@/api/crm/contacts";
import {crmProductDownloadExcelAPI, crmProductExcelImportAPI} from "@/api/crm/product";
import {crmDownImportErrorAPI, crmQueryImportInfoAPI, crmQueryImportNumAPI, filedGetFieldAPI} from "@/api/crm/common";
import {downloadExcelWithResData, verifyFileTypeWithFileName} from "utils";


import WkUserSelect from '/src/szcomponent/NewCom/SzDeptUserComp/WkUserSelect/index.vue'
import ImportHistory from './ImportHistory.vue'
import XrImport from './XrImport.vue'

import crmTypeModel from '/src/views/crm/model/crmTypeModel.js'
import Lockr from 'lockr'
import merge from '/src/utils/merge.js'
import {ElMessage} from "element-plus";

// 引入消息总线
const cxt = getCurrentInstance() //相当于Vue2中的this
const bus = cxt.appContext.config.globalProperties.$bus

const DefaultProps = {
  typeName: '', // 模块名称
  ownerSelectShow: false,
  poolSelectShow: false, // 代表是公海 导入模板也不一样
  historyShow: true,
  repeatHandleShow: true,
  repeatRuleShow: true, // 步骤二的重复规则是否展示
  importRequest: null, // 导入请求
  importParams: null, // 导入参数
  templateRequest: null, // 模板请求
  templateParams: null, // 导入模板参数
  noImportProcess: false, // 无导入过程，上传完附件直接出结果
  downloadErrFuc: null, // 自定义下载错误的方法
  userInfo: null // 当前登录人信息
}


defineProps({
  name: 'WkCRMImport', // 文件导入

})

const emits = defineEmits(['status',])



const loading = ref(false)
const fieldList = ref([])
const repeatHandling = ref(1) // 	1 覆盖，2跳过
const file = ref({name: ''})
const user = ref('')

// 公海数据
const poolId = ref('')
const poolList = ref([])

const stepsActive = ref(1)
const stepList = ref([
  {
    icon: 'wk wk-upload',
    title: '上传文件',
    status: 'wait'
  },
  {
    icon: 'wk wk-data-import',
    title: '导入数据',
    status: 'wait'
  },
  {
    icon: 'wk wk-success',
    title: '导入完成',
    status: 'wait'
  }
])
const resultData = ref(null)
const processData = ref({
  count: 0,
  status: ''
})
const messageId = ref(null)
const intervalTimer = ref(null)

const historyPopoverShow = ref(false)

const showCRMImport = ref(false)
const crmType = ref('')
const crmProps = ref(null)
const crmImportStatus = ref('')
const cacheShow = ref(false) // 缓存展示
const cacheDone = ref(false) // 缓存导入是否完成
const userInfo = ref(null)


const crmTypeName = computed(() => {
  if (crmProps.value && crmProps.value.typeName) {
    return crmProps.value.typeName
  }
  return (
      {
        customer: '客户',
        leads: '线索',
        contacts: '联系人',
        product: '产品'
      }[crmType.value] || ''
  )
})

const importLoadingText = computed(() => {
  if (processData.value.count) {
    return `数据导入中（当前已导入${processData.value.count}条）`
  }

  return '数据导入中'
})

const sureTitle = computed(() => {
  return {
    1: '立即导入',
    2: '最小化',
    3: '确定'
  }[stepsActive.value]
})

const showCancel = computed(() => {
  return stepsActive.value != 2
})

const fieldUniqueInfo = computed(() => {
  const uniqueList = fieldList.value.filter(item => item.isUnique == 1)

  return uniqueList.map(item => item.name).join('/') || '无'
})

const config = computed(() => {
  return merge({...DefaultProps}, crmProps.value || {})
})

// 1.导入框展示 2.导入状态状态为空或者是等待状态  缩小框不展示
const showFixImport = computed(() => {
  return !showCRMImport.value && crmImportStatus.value && crmImportStatus.value != 'wait'
})






watch(cacheShow, (val) => {
  // 展示缓存
  if (val) {
    // this.$emit('update:cacheShow', false)
    cacheShow.value = false
    const beforeImportInfo = Lockr.get('crmImportInfo')
    if (beforeImportInfo && beforeImportInfo.messageId) {
      loading.value = true
      messageId.value = beforeImportInfo.messageId
      stepList.value[0].status = 'finish'

      if (cacheDone.value) {
        stepList.value[1].status = 'finish'
        stepsActive.value = 3
        thirdQueryResult()
      } else {
        stepsActive.value = 2
        stepList.value[1].status = 'process'
      }

      loopSecondQueryNum()
    }
  }
}, {
  immediate: true
})


watch(showCRMImport, (val) => {
  if (val) {
    // 阶段一展示 需要获取的信息
    if (stepsActive.value == 1) {
      if (config.value.userInfo) {
        user.value = config.value.userInfo.userId
      }

      if (config.value.poolSelectShow) {
        getPoolList()
      }

      if (config.value.repeatRuleShow && config.value.repeatHandleShow) {
        getField()
      }
    }
  } else {
    if (stepsActive.value == 3) {
      resetData()
    }

    fieldList.value = []
  }
}, {
  immediate: true
})

watch(stepsActive, () => {
  // this.$emit('status', {
  //   1: 'wait',
  //   2: 'process',
  //   3: 'finish'
  // }[this.stepsActive])

  crmImportChange({
    1: 'wait',
    2: 'process',
    3: 'finish'
  }[stepsActive.value])
})

function created() {
  // 处理上次缓存
  const beforeImportInfo = Lockr.get('crmImportInfo')
  if (beforeImportInfo && beforeImportInfo.messageId) {
    crmType.value = beforeImportInfo.crmType
    crmProps.value = beforeImportInfo.crmProps
    lockrSecondQueryNum(beforeImportInfo.messageId)
    cacheShow.value = true
  } else {
    cacheShow.value = false
  }
}

created()


const importFile = (crmType, props) => {
  if (crmType.value != crmType && showFixImport.value) {
    ElMessage.error({message: '请先处理当前导入的数据'})
  } else {
    crmType.value = crmType
    crmProps.value = props
    showCRMImport.value = true
  }
}

function sureClick() {
  if (stepsActive.value == 1) {
    if (stepList.value[0].status == 'finish') {
      stepList.value[1].status = 'process'
      stepsActive.value = 2
      firstUpdateFile(res => {
        const resData = res.data.data || {}
        if (config.value.noImportProcess) {
          loading.value = false
          stepList.value[1].status = 'finish'
          stepsActive.value = 3
          emits('status', 'finish')
          resultData.value = resData
          if (resData.errSize > 0) {
            stepList.value[2].status = 'error'
          } else {
            stepList.value[2].status = 'finish'
          }
        } else {
          messageId.value = resData

          // 写入本次缓存
          Lockr.set('crmImportInfo', {
            messageId: messageId.value,
            crmProps: config.value,
            crmType: crmType.value
          })

          loopSecondQueryNum()
        }
      })
    } else {
      if (!file.value.name) {
        ElMessage.error({message: '请选择导入文件'})
      } else if (
          config.value.ownerSelectShow && !user.value
      ) {
        ElMessage.error({message: '请选择负责人'})
      }
    }
  } else {
    closeView()
  }
}


/**
 * 第一步上传
 */
function firstUpdateFile(result) {
  let params = {}
  params.repeatHandling = repeatHandling.value
  params.file = file.value
  if (config.value.ownerSelectShow) {
    params.ownerUserId = user.value
  }
  if (config.value.poolSelectShow) {
    params.poolId = poolId.value
  }

  const request = config.value.importRequest || {
    customer: config.value.poolSelectShow ? crmCustomerPoolExcelImportAPI : crmCustomerExcelImportAPI,
    leads: crmLeadsExcelImportAPI,
    contacts: crmContactsExcelImportAPI,
    product: crmProductExcelImportAPI
  }[crmType.value]
  loading.value = true
  if (config.value.importParams) {
    params = {
      ...params,
      ...config.value.importParams
    }
  }
  request(params).then(res => {
    if (result) {
      result(res)
    }
  }).catch(() => {
    if (result) {
      result(false)
    }
    loading.value = false
  })
}

/**
 * 第二步查询数量
 */
function loopSecondQueryNum() {
  secondQueryNum()
  intervalTimer.value = setInterval(() => {
    if (processData.value.status == 'end') {
      clearInterval(intervalTimer.value)
      intervalTimer.value = null
      thirdQueryResult()
    } else {
      secondQueryNum()
    }
  }, 2000)
}

function secondQueryNum() {
  crmQueryImportNumAPI({messageId: messageId})
      .then(res => {
        if (res.data === null) {
          processData.value.status = 'end'
        } else {
          processData.value.status = ''
          processData.value.count = res.data
        }
      })
      .catch(() => {
        // this.processData.status = 'err'
      })
}

/**
 * 第三部 查询结果
 */
function thirdQueryResult() {
  crmQueryImportInfoAPI({messageId: messageId.value})
      .then(res => {
        loading.value = false
        stepList.value[1].status = 'finish'
        stepsActive.value = 3
        emits('status', 'finish')
        if (res) {
          resultData.value = res.data
          if (res.data.errSize > 0) {
            stepList.value[2].status = 'error'
          } else {
            stepList.value[2].status = 'finish'
          }
        }
      })
      .catch(() => {
      })
}

/**
 * 下载错误模板
 */
function downloadErrData(result) {
  loading.value = true
  if (config.value.downloadErrFuc) {
    config.value.downloadErrFuc(result).then(res => {
      downloadExcelWithResData(res)
      loading.value = false
    })
        .catch(() => {
          loading.value = false
        })
  } else {
    crmDownImportErrorAPI({messageId: messageId.value})
        .then(res => {
          downloadExcelWithResData(res)
          loading.value = false
        })
        .catch(() => {
          loading.value = false
        })
  }
}

// 下载模板操作
function download() {
  const request = config.value.templateRequest || {
    customer: config.value.poolSelectShow ? crmCustomerPoolDownloadExcelAPI : crmCustomerDownloadExcelAPI,
    leads: crmLeadsDownloadExcelAPI,
    contacts: crmContactsDownloadExcelAPI,
    product: crmProductDownloadExcelAPI
  }[crmType.value]
  request(config.value.templateParams || {})
      .then(res => {
        downloadExcelWithResData(res)
      })
      .catch(() => {
      })
}

// 选择文件
function selectFile() {
  document.getElementById('importInputFile').click()
}

/** 图片选择出发 */
function uploadFile(event) {
  var files = event.target.files
  const file = files[0]
  if (verifyFileTypeWithFileName(file.name)) {
    file.value = file
    // 阶段一状态
    getFirstStepStatus()
  }
  event.target.value = ''
}

// 用户选择
function userSelect(data) {
  // 阶段一状态
  getFirstStepStatus()
}

function getFirstStepStatus() {
  // 阶段一状态
  const hasFile = file.value && file.value.size
  const hasUser = !!user.value

  if (config.value.ownerSelectShow) {
    stepList.value[0].status = hasFile && hasUser ? 'finish' : 'wait'
  } else {
    stepList.value[0].status = hasFile ? 'finish' : 'wait'
  }
}

/**
 * 公海数据
 */
function getPoolList() {
  crmCustomerPoolNameListAPI()
      .then(res => {
        poolList.value = res.data.data || []
        poolId.value = poolList.value.length > 0 ? poolList.value[0].poolId : ''
      })
      .catch(() => {
      })
}

// 关闭操作
function closeView() {
  // this.$emit('update:show', false)
  showCRMImport.value = false
  if (stepsActive.value == 3) {
    bus.emit('import-crm-done-bus', crmType.value)
    Lockr.rm('crmImportInfo')
  }
  // this.$emit('close', this.stepsActive == 3 ? 'finish' : '')
  crmImportClose(stepsActive.value == 3 ? 'finish' : '')
}

/**
 * 重置页面数据
 */
function resetData() {
  repeatHandling.value = 1
  file.value = {name: ''}
  user.value = ''

  stepsActive.value = 1
  stepList.value = [
    {
      icon: 'wk wk-upload',
      title: '上传文件',
      status: 'wait'
    },
    {
      icon: 'wk wk-data-import',
      title: '导入数据',
      status: 'wait'
    },
    {
      icon: 'wk wk-success',
      title: '导入完成',
      status: 'wait'
    }
  ]
  resultData.value = null
  processData.value = {
    count: 0,
    status: ''
  }
  messageId.value = null
}

/**
 * 获取验证字段
 */
function getField() {
  let params = {
    label: crmTypeModel[crmType.value],
    type: 1
  }

  filedGetFieldAPI(params).then(res => {
    fieldList.value = res.data.data
  }).catch(() => {
  })
}


function crmImportChange(status) {
  crmImportStatus.value = showCRMImport.value && status == 'finish' ? '' : status
}

function fixImportClick() {
  showCRMImport.value = true
}

function crmImportClose(status) {
  if (status == 'finish') {
    crmImportStatus.value = ''
  }
}

/**
 * 第二步查询数量
 */
function lockrSecondQueryNum(messageId) {
  crmQueryImportNumAPI({messageId: messageId})
      .then(res => {
        if (res.data.data === null) { // 结束 否则 进行中
          crmImportStatus.value = 'finish'
          cacheDone.value = true
        } else {
          cacheDone.value = false
          crmImportStatus.value = 'process'
        }
        showCRMImport.value = false
      })
      .catch(() => {
        Lockr.rm('crmImportInfo')
      })
}


defineExpose({
  importFile
})


</script>

<style scoped lang="scss">
.el-steps {
  margin-bottom: 15px;

  :deep(.el-step__title) {
    font-size: 14px;
  }

  :deep(.el-step.is-simple .el-step__arrow::before),
  :deep(.el-step.is-simple .el-step__arrow::after) {
    height: 10px;
    width: 2px;
  }

  :deep(.el-step.is-simple .el-step__arrow::after) {
    transform: rotate(45deg) translateY(3px);
  }

  :deep(.el-step.is-simple .el-step__arrow::before) {
    transform: rotate(-45deg) translateY(-2px);
  }
}

.step-section {
  min-height: 300px;
  position: relative;

  :deep(.el-loading-spinner) {
    top: 45%;

    .el-icon-loading {
      font-size: 40px;
      color: #999;
    }

    .el-loading-text {
      color: #333;
      margin: 8px 0;
    }
  }

  &__tips {
    color: #999;
    font-size: 12px;
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    text-align: center;
    z-index: 3000;
  }
}

.sections {
  font-size: 14px;
  color: #333;

  &__title {
    font-weight: 600;
  }

  &__tips {
    padding-left: 30px;
    margin: 8px 0 15px;
    color: #999;
    font-size: 12px;
    line-height: 1.4;
  }

  .download {
    cursor: pointer;
    color: #2362FB;
  }

}

.sections__tips + .content {
  padding-top: 0;
}

.content {
  padding: 10px 10px 10px 30px;

  .el-select {
    width: 400px;
  }

  .user-cell {
    width: 400px;
  }
}

#importInputFile {
  display: none;
}

.file-select {
  .el-input {
    width: 400px;
  }

  button {
    margin-left: 20px;
  }
}

.is-hidden {
  visibility: hidden;
}

.history-btn {
  float: left;
  margin-left: 15px;
}


// 结果信息
.result-info {
  text-align: center;
  padding-top: 80px;

  &__icon {
    font-size: 40px;
    color: $xr-color-primary;
  }

  &__des {
    margin-top: 15px;
    color: #333;
    font-size: 14px;
  }

  &__detail {
    margin-top: 15px;
    font-size: 12px;
    color: #666;

    &--all {
      color: #333;
      font-weight: 600;
    }

    &--suc {
      color: $xr-color-primary;
      font-weight: 600;
    }

    &--err {
      color: #f94e4e;
      font-weight: 600;
    }
  }

  &__btn--err {
    margin-top: 10px;
  }
}
</style>
